package org.example.streamtest;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * file:StreamTest.class
 * function:
 *
 * @author shaodan wang
 * @date 2024-10-20
 */


public class StreamTest {
    public List<Person> personList = new ArrayList<>();
    {
        personList.add(new Person("Tom", 8900, 90,"male", "New York"));
        personList.add(new Person("Jack", 7000, 40,"male", "Washington"));
        personList.add(new Person("Lily", 7800, 50,"female", "Washington"));
        personList.add(new Person("Anni", 8200, 60,"female", "New York"));
        personList.add(new Person("Owen", 9500, 70,"male", "New York"));
        personList.add(new Person("Alisa", 7900, 23,"female", "New York"));
    }
    @Data
    public static class Person {
        private String name;  // 姓名
        private int salary; // 薪资
        private int age; // 年龄
        private String sex; //性别
        private String area;  // 地区

        // 构造方法
        public Person(String name, int salary, int age,String sex,String area) {
            this.name = name;
            this.salary = salary;
            this.age = age;
            this.sex = sex;
            this.area = area;
        }
    }


    @Test
    public void test001(){
        List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
        // 遍历输出符合条件的元素
        list.stream().forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer inputRes) {
                System.out.print(inputRes); //这里会打印出 7693821
            }
        });
        //没学过Optional的可以看我的文章：
        // https://blog.csdn.net/weixin_46269045/article/details/142681907

        // 匹配第一个（这里是有序的，所以不能用并行流。但是他不会返回一个数据对象，而是返回一个Optional，
        Optional<Integer> findFirst = list.stream().findFirst();
        Integer findFirstInt = findFirst.get();//结果是7
        // 匹配任意，这里返回（适用于并行流）
        Optional<Integer> findAny = list.parallelStream().findAny();
        Integer findAnyInt = findAny.get(); // 结果是任何一个数字
        // 是否包含符合特定条件的元素
        //判断这个集合是否包含一个及其以上的满足该条的结果
        //下面的结果返回true，因为7 9 8 都大于6
        boolean anyMatch = list.stream().anyMatch(new Predicate<Integer>() {
            @Override
            public boolean test(Integer inputRes) {
                return inputRes > 6;
            }
        });

         list.stream().filter(new Predicate<Integer>() { //过滤
            @Override
            public boolean test(Integer inputRes) {
                return inputRes > 7; //凡是满足这个的结果，都会被收纳
            }
        }).forEach(new Consumer<Integer>() { //遍历操作
            @Override
            public void accept(Integer inputRes) {
                System.out.println(inputRes); //输出8和9
            }
        });

        List<Person> personList = new ArrayList<>();
        personList.add(new Person("Tom", 8900, 23, "male", "New York"));
        personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
        personList.stream().filter(new Predicate<Person>() {
            @Override
            public boolean test(Person person) {
                return person.getSalary() > 8000; //筛选薪资是否大于8000
            }
        }).forEach(new Consumer<Person>() {
            @Override
            public void accept(Person person) {
                System.out.println(person.getName()); //打印  Tom
            }
        });
    }


    @Test
    public void test002(){


        List<Double> doubleList = Arrays.asList(1.0, 2.0, 3.0, 4.0, 2.0);
        double average = doubleList.stream().mapToDouble(new ToDoubleFunction<Double>() {
                    @Override
                    public double applyAsDouble(Double value) {
                        //这里可以做一些额外的处理操作，具体就不详细说明了。
                        return value;
                    }
                })
                .average()//直接求平均值，简单方便 还有其他的.sum()以及.max()等来求出总和以及最大值
                .getAsDouble();//获得到最后的值


        double sum = doubleList.stream().mapToDouble(Number::doubleValue).sum();
        double max = doubleList.stream().mapToDouble(Number::doubleValue).max().getAsDouble();
        System.out.println("平均值：" + average + "，总和：" + sum + "，最大值：" + max);
    }

    @Test
    public void test003(){
        List<Integer> list = Arrays.asList(1, 3, 2, 8, 11, 4);
        // 求和方式1
        Optional<Integer> sum = list.stream().reduce(new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer int1, Integer int2) {
                //最后求出集合的最大值
                return Math.max(int1,int2);
            }
        });//这里返回的不是一个规约后的结果，是一个Optional Optional不会的可以去看下我写的Optional讲解
    }


}
